/**
 * @author: mattwang@tencent.com
 * @date: 2012-10-20
 */

#ifndef __SVD_CORE_H__
#define __SVD_CORE_H__

#include <ctime>
#include <cstring>
#include <climits>
#include <string>
#include <cstdlib>

#include "type_def.h"
#include "param_def.h"

#include "svd_trainer.h"

// class for RMSE evaluation
class RMSEEvaluator {
private:
	long double sum_test, num_test;
public:
	inline void init() {
		this->before_first();
	}
	inline void add_eval(float label, float pred, float scale = 1.0f) {
		double diff = (pred - label) * scale;
		sum_test += diff * diff;
		num_test += 1.0;
	}
	inline void print_stat(FILE *fo, int iter) {
		fprintf(fo, "%d\t%lf\n", iter, sqrt(sum_test / num_test));
	}
	inline void before_first() {
		sum_test = 0.0f;
		num_test = 0.0f;
	}
};

class SvdCore {
private:
	// type of model
	SvdTrainer *svd_trainer;
private:
	int input_type;
	IDataIterator<ReDataBlock> *itr_plus;
private:
	// initialize end
	int init_end;

	int num_round, train_repeat;
private:
	void reset_default();
public:
	SvdCore() {
		this->reset_default();
	}
	virtual ~SvdCore() {
		if (init_end) {
			delete svd_trainer;
			if (itr_plus != NULL)
				delete itr_plus;
		}
	}
private:
	void SvdCore::load_model();

	void SvdCore::save_model();

	void init(void);

	int sync_latest_model();
	void update(int r, unsigned long elapsed, time_t start);

public:
	void train();
};

#endif // __SVD_CORE_H__
